#pragma once

class CNotifyCommands :	
	public INotifyCommands//,
	//public INotifyCommands
{
private:

	typedef CAtlList<INotifyCommand*>	CNCList;
	CNCList m_ncList;

public:
	CNotifyCommands(void)
	{
	}

	~CNotifyCommands(void)
	{
	}

	STDMETHODIMP Add(INotifyCommand* pNotifyCommand)
	{
		if (pNotifyCommand != NULL)
		{
			m_ncList.AddTail(pNotifyCommand);
			pNotifyCommand->AddRef();
			return S_OK;
		}

		return S_FALSE;
	}

	STDMETHODIMP Remove(INotifyCommand* pNotifyCommand)
	{
		POSITION pos = NULL;
		if (pNotifyCommand != NULL)
		{
			pos = m_ncList.Find(pNotifyCommand);

			m_ncList.RemoveAt(pos);
			pNotifyCommand->Release();
			return S_OK;
		}

		return S_FALSE;
	}

	STDMETHODIMP RemoveAll()
	{
		POSITION pos = m_ncList.GetHeadPosition();
		INotifyCommand *pnc;

		while (pos != NULL)
		{
			pnc = m_ncList.GetNext(pos);
			pnc->Release();
		}

		if (m_ncList.GetCount() > 0)
		{
			m_ncList.RemoveAll();
		}

		return S_OK;
	}

	STDMETHODIMP get_Count(LONG* nCount)
	{
		*nCount = m_ncList.GetCount();
		return S_OK;
	}

	virtual HRESULT STDMETHODCALLTYPE Next( 
		/* [in]  */ ULONG celt,
		/* [out] */ IUnknown **rgelt,
		/* [out] */ ULONG *pceltFetched)
	{
		return S_FALSE;
	}

	virtual HRESULT STDMETHODCALLTYPE Skip( 
		/* [in] */ ULONG celt)
	{
		return S_FALSE;
	}


	virtual HRESULT STDMETHODCALLTYPE Reset( void)
	{
		return S_FALSE;
	}


	virtual HRESULT STDMETHODCALLTYPE Clone( 
		/* [out] */ IEnumUnknown **ppenum)
	{
		return S_FALSE;
	}

	STDMETHODIMP QueryState(UINT nCmdID, ICommandItem *pCmdUI)
	{
		HRESULT			hr			= S_FALSE;
		VARIANT_BOOL	bCmdHandle	= VARIANT_FALSE;

		if (m_ncList.GetCount() == 0)
		{
			pCmdUI->put_CmdHandle(VARIANT_TRUE);
			return hr;
		}

		POSITION pos = m_ncList.GetHeadPosition();
		INotifyCommand *pnc;

		while (pos != NULL)
		{
			pnc = m_ncList.GetNext(pos);
			hr = pnc->QueryState(nCmdID, pCmdUI);
			pCmdUI->get_CmdHandle(&bCmdHandle);
			if (bCmdHandle == VARIANT_FALSE)
				break;
		}

		return hr;
	}


	STDMETHODIMP NotifyCommand(UINT codeNotify, int nCmdID, ICommandItem *pCmdUI)
	{
		HRESULT hr = S_FALSE;
		INotifyCommand *pNC;
		POSITION pos = m_ncList.GetHeadPosition();
		VARIANT_BOOL	bCmdHandle = VARIANT_FALSE;

		if (m_ncList.GetCount() == 0)
		{
			pCmdUI->put_CmdHandle(VARIANT_TRUE);
			return hr;
		}

		pCmdUI->put_CmdHandle(VARIANT_FALSE);
		while (pos != NULL)
		{
			pNC = m_ncList.GetNext(pos);
			hr = pNC->NotifyCommand(codeNotify, nCmdID, pCmdUI);

			pCmdUI->get_CmdHandle(&bCmdHandle);
			if (bCmdHandle == VARIANT_FALSE)
				break;
		}

		return hr;
	}

	STDMETHODIMP NotifyCommandPoint(UINT nCmdID, POINT *pt, ICommandItem *pCmdUI, IDispatch *ppmb)
	{
		HRESULT			hr = S_FALSE;
		INotifyCommand	*pNC;
		POSITION		pos = m_ncList.GetHeadPosition();
		VARIANT_BOOL	bCmdHandle = VARIANT_FALSE;

		if (m_ncList.GetCount() == 0)
		{
			pCmdUI->put_CmdHandle(VARIANT_TRUE);
			return hr;
		}

		pCmdUI->put_CmdHandle(VARIANT_FALSE);
		while (pos != NULL)
		{
			pNC = m_ncList.GetNext(pos);
			hr = pNC->NotifyCommandPoint(nCmdID, pt, pCmdUI, ppmb);

			pCmdUI->get_CmdHandle(&bCmdHandle);
			if (bCmdHandle == VARIANT_FALSE)
				break;
		}

		return hr;
	}

	STDMETHODIMP GetCommandTips(UINT nCmdID, BSTR *bstrTips)
	{
		HRESULT hr = S_FALSE;
		INotifyCommand *pNC;
		POSITION pos = m_ncList.GetHeadPosition();

		while (pos != NULL)
		{
			pNC = m_ncList.GetNext(pos);
			hr = pNC->GetCommandTips(nCmdID, bstrTips);

			if (SysStringLen(*bstrTips) > 0)
				break;
		}

		return hr;
	}

	STDMETHODIMP ExpansionCommand(UINT nCmdID, ICommandItem *pCmdUI)
	{
		HRESULT hr = S_FALSE;

		INotifyCommand *pNC;
		POSITION pos = m_ncList.GetHeadPosition();
		VARIANT_BOOL	bCmdHandle = VARIANT_FALSE;

		pCmdUI->put_CmdHandle(VARIANT_TRUE);
		while (pos != NULL)
		{
			pNC = m_ncList.GetNext(pos);
			hr = pNC->ExpansionCommand(nCmdID, pCmdUI);

			pCmdUI->get_CmdHandle(&bCmdHandle);
			if (bCmdHandle == VARIANT_FALSE)
				break;
		}

		return hr;
	}

};

